/**
 * @file ble_comp.c
 * @brief
 *
 * @version 0.1
 * @date 2023-09-05
 *
 * @copyright  Copyright (c) 2020~2030 ShenZhen dingxintongchuang Technology Co., Ltd.
 * All rights reserved.
 *
 * @note          鼎新同创・智能锁
 *
 * @par 修改日志:
 * <1> 2023-09-05 v0.1 tianshidong 创建初始版本
 * *************************************************************************
 */
#include "device.h"
#include "component.h"
#include "../ble.h"
#include "debug_config.h"
#include "ble_comp.h"

#define EVENT_TEST (0X00000001)                /// 超时事件
#define EVENT_BLE_MULTIPLE_PACKET (0X00000002) /// 超时事件

#define BLE_PROTOCOL_CMD_PACKET_STX 0XA5E5 //命令包数据头 固定为：0xA5 0xE5

#define BLE_PROTOCOL_RX_CMD_BUF_QTY (5) //最多缓存命令数量 // 
#define BLE_SID_DEFAULE_VALUE 0         // 包编号默认值
#define BLE_MAX_SEND_PAYLOAD_LEN 100     //每包数据最大长度，超过这个数据需要分包

#define LKMD    0x03
#define APP     0x04

uint32_t rand_code_ack = 0;
static uint32_t random_get = 0;

static uint8_t ble_encryption_flag = 0;
static uint8_t aeskey[16] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static uint8_t data_temp[100] = {};
static uint32_t data_length = 0;
#pragma pack(1)

enum
{
    TX_STA_IDLE = 0, //空闲
    TX_STA_BUSY = 1, //已唤醒
} status;
static struct
{
    struct
    {
        uint8_t param[BLE_COMP_BUFFER_SIZE]; //收到的命令参数
        uint16_t paramLen;                   //参数长度
    } rxBuffer[BLE_PROTOCOL_RX_CMD_BUF_QTY]; //最多缓存10条rxCmd
    uint8_t index;                           // buf索引
    uint16_t cmdTimes;                       //命令执行次数：收到命令后第一次执行回调，次数设置为0

    uint8_t DataIndex;                      //分包buf索引
    uint8_t DataBuff[BLE_COMP_BUFFER_SIZE]; //分包数据缓存
    uint16_t DataBuffLen;                   //分包数据已存储长度

    uint32_t ackSendTimeStamp; //最后一次发出应答包的时间（用来控制发出多个应答包的间隔时间）
} CmdPacketRxInfo;//

/* 命令包发送状态信息：记录蓝牙和Zigbee两个设备的发送状态 */
static struct
{
    uint8_t status;                            //当前发送的状态
    uint8_t dataBuf[BLE_COMP_BUFFER_SIZE];     //发送缓存
    uint8_t sendbuf[BLE_COMP_BUFFER_SIZE + 10]; //发送最大长度//
    uint8_t curDataLen;                        //当前发送数据长度
    uint32_t random_value;                      //通讯随机码
    uint8_t totalDataLen;                      //整包数据长度
    uint8_t packetNum;
} CmdPacketTxInfo;

/* HK01蓝牙协议命令格式 */
typedef struct
{
    uint16_t start;     //固定为：0xA5 0xE5, 表示数据包的起始
    uint16_t dataLen;   //数据帧长度，从 dst_addr(包含 dst_addr)到 checksum(包含 checksum)的数据长度
    uint8_t dst_addr;   //数据目标模组地址
    uint8_t src_addr;   //数据来源模组地址
    uint32_t random_code;//通讯随机码--获取随机码指令该字段为 0x1
    //帧负载数据--按小端方式排放--结构体成员按 1 字节对齐方式排列
    // struct 
    // {
    //     uint16_t ver : 4;      //  消息结构定义版本号。目前使用版本号固件为 1
    //     uint16_t type: 2;     //  消息类型：NON（0，不需要应答的数据）、CON（1，必须要应答的数据）、ACK（3， 针对某个 CON 的应答数据） 
    //     uint16_t seq : 10;    // 消息序号，用于匹配应答，应答包 seq 需和请求包 seq 一致。
    //     uint16_t cmd;         // 消息命令号，标识消息用途和 data 结构。
    //     uint8_t dataBuf[];    //消息负载数据，具体长度依具体数据而定。
	// 	//uint16_t checksum;   //校验码(放在负载数据的最后两个字节)：CRC16 ( dataLen + dst_addr + src_addr + random_code + data )
    // }Payload;      
	//rxBuffer[BLE_PROTOCOL_RX_CMD_BUF_QTY]; //最多缓存10条rxCmd
    uint8_t dataBuf[];
} BleCmdPacket_stu_t;
#pragma pack()

/* 创建环形缓存，保存处理好的命令包，准备发送给应用层 */
static RingBufferHandle_t rbBleHandle = NULL; /// app发过来的内容
/**
  * @brief  计算CRC校验
  * @note   CRC16的校验算法为XMODEM 
  *
  * @param  puchMsg：数据指针
  * @param  usDataLen：数据长度
  */
static uint16_t CRC16_Cal(uint8_t *puchMsg, uint32_t usDataLen)
{
    unsigned short wCRCin = 0x0000;
    unsigned short wCPoly = 0x1021;
    unsigned char wChar = 0;

    while (usDataLen--)
    {
        wChar = *(puchMsg++);
        wCRCin ^= (wChar << 8);

        for(int i = 0; i < 8; i++)
        {
            if(wCRCin & 0x8000)
            {
                wCRCin = (wCRCin << 1) ^ wCPoly;
            }
            else
            {
                wCRCin = wCRCin << 1;
            }
        }
    }
    return (wCRCin) ;
}

/**
 * @brief   发送数据给应用层（COMP->应用层)
 *
 * @note
 */
static void BleTask_MessagePublish(uint8_t len, uint8_t *pData, uint8_t cmd, uint8_t type)
{
    BlePublishMsg_t *msg = NULL;
    msg = (BlePublishMsg_t *)OSAL_Malloc(len + sizeof(BlePublishMsg_t));
    if (msg == NULL)
    {
        BLE_TASK_LOG_E("msg publish err\r\n");
        return;
    }
    memset(msg, 0, len + sizeof(BlePublishMsg_t));
    msg->type = type;
    msg->cmd = cmd;
    msg->len = len;
    if((len != 0)&&(pData != NULL))
    {
        memcpy(msg->pData, pData, len);
    }
    OSAL_MessagePublish(msg, len + sizeof(BlePublishMsg_t));
    OSAL_Free(msg);
}
/**
 * @brief
 *
 * @param [in] dataBuf
 * @param [in] len
 *
 * @note
 */
static void BleTask_SendData_to_driver(uint8_t *dataBuf, uint8_t len)
{
    BLE_TASK_LOG_HEX("BleTask SendData", dataBuf, len);
    if (len > 30)
    {
        memset (data_temp, 0, sizeof(data_temp));
        memcpy(data_temp, dataBuf, len);
        data_length = len;
        OSAL_EventRepeatCreate(COMP_BLE, EVENT_BLE_MULTIPLE_PACKET, 20, EVT_PRIORITY_MEDIUM); //100
    }
    else
    {
        Device_Write(vBLE_0, dataBuf, len, BLE_CTRL_DATA);
        if (CmdPacketTxInfo.status == TX_STA_BUSY && CmdPacketTxInfo.totalDataLen == CmdPacketTxInfo.curDataLen)
        {
            memset(&CmdPacketTxInfo.dataBuf, 0, sizeof(CmdPacketTxInfo.dataBuf));
            CmdPacketTxInfo.totalDataLen = 0;
            CmdPacketTxInfo.curDataLen = 0;
            CmdPacketTxInfo.status = TX_STA_IDLE;
        }
    }
}

/**
 * @brief 发送处理
 *
 * @param [in] sid 包序号
 * @param [in] totalLen 数据总长度
 * @param [in] curLen 当前包数据长度
 * @param [in] dataBuf 数据缓存
 *
 * @note
 */
static void BleTask_SendCmdPacket(uint32_t random, uint8_t totalLen, uint8_t curLen, uint8_t *dataBuf)//uint16_t
{
    BleCmdPacket_stu_t *pCmdPacket = (BleCmdPacket_stu_t *)CmdPacketTxInfo.sendbuf;
    uint16_t crc16 = 0;
    uint32_t encryptionDataLen = 0; 
    uint8_t Ble_send[BLE_COMP_BUFFER_SIZE]; //发送数据

    memset(Ble_send, 0, BLE_COMP_BUFFER_SIZE);
    if ((totalLen > (BLE_COMP_BUFFER_SIZE - 10)) && curLen > BLE_MAX_SEND_PAYLOAD_LEN)//--
    {
        BLE_TASK_LOG_W("ble send packet payload len is error");
    }

   pCmdPacket->start = OSAL_SWAP16(BLE_PROTOCOL_CMD_PACKET_STX);
   //pCmdPacket->dataLen = OSAL_SWAP16(curLen);//
   pCmdPacket->dst_addr = APP;
   pCmdPacket->src_addr = LKMD; 
   pCmdPacket->random_code = random;
    //读一下加密标志位
    OSAL_NvRead(OSAL_OFFSET(BleNvData_stu_t, ble_encryptionflag), &ble_encryption_flag, 1);
    BLE_TASK_LOG_D("ble_encryption_flag read:%d  ",ble_encryption_flag);
    if(ble_encryption_flag != 1)
    {
        ble_encryption_flag = 0;
    }

    if (ble_encryption_flag == 0) 
    {
        memcpy(pCmdPacket->dataBuf, &dataBuf[8], curLen - 8);
    }
    else if(ble_encryption_flag == 1)
    {
        //AES128加密_PKCS7  decryptiondata
        encryptionDataLen = curLen - 8;//12
        BLE_TASK_LOG_D("<<encryptionDataLen:%x\n",encryptionDataLen);
        BLE_TASK_LOG_HEX("<<decryptiondata", &dataBuf[8], encryptionDataLen);
        OSAL_Crypto(AES128_ENCRYPTION_PKCS7, &dataBuf[8], encryptionDataLen, Ble_send, aeskey);
        if (encryptionDataLen % 16 != 0)
        {
            encryptionDataLen = (16 - (encryptionDataLen % 16)) + encryptionDataLen;//10
        }
        BLE_TASK_LOG_HEX("<<encryptiondata", Ble_send, encryptionDataLen);
        memcpy(pCmdPacket->dataBuf, Ble_send, encryptionDataLen);
    }
    

    if (ble_encryption_flag == 0)
    {
        pCmdPacket->dataLen = OSAL_SWAP16(curLen);
        crc16 = CRC16_Cal(&pCmdPacket->dataLen, curLen);
        BLE_TASK_LOG_D("001 crc16:%x\n",crc16);
        pCmdPacket->dataBuf[curLen - 8] = (uint8_t)((crc16 & 0xFF00) >> 8);
        pCmdPacket->dataBuf[curLen - 7] = (uint8_t)(crc16 & 0x00FF);

         BleTask_SendData_to_driver(CmdPacketTxInfo.sendbuf, 4 + curLen);
    }
    else if(ble_encryption_flag == 1)
    {
        pCmdPacket->dataLen = OSAL_SWAP16(encryptionDataLen + 8);//10
        crc16 = CRC16_Cal(&pCmdPacket->dataLen, encryptionDataLen + 8);
        BLE_TASK_LOG_D("002 crc16:%x\n",crc16);
        BLE_TASK_LOG_D("encryptionDataLen:%d\n",encryptionDataLen);
        pCmdPacket->dataBuf[encryptionDataLen] = (uint8_t)((crc16 & 0xFF00) >> 8);
        pCmdPacket->dataBuf[encryptionDataLen + 1] = (uint8_t)(crc16 & 0x00FF); 

        BleTask_SendData_to_driver(CmdPacketTxInfo.sendbuf, encryptionDataLen + 12);//
    }
    

  //  BleTask_SendData_to_driver(CmdPacketTxInfo.sendbuf, 4 + curLen);//
}
/**
 * @brief 多包数据发送处理
 *TODO: 上报分包消息(0xB001)
 *
 * @note
 */
static void BleTask_Multi_packet_send(void)
{
    // if (CmdPacketTxInfo.SID == CmdPacketTxInfo.packetNum)
    // {
    //     CmdPacketTxInfo.curDataLen = CmdPacketTxInfo.totalDataLen - ((CmdPacketTxInfo.SID - 1) * BLE_MAX_SEND_PAYLOAD_LEN);
    // }
    // else if (CmdPacketTxInfo.SID < CmdPacketTxInfo.packetNum)
    // {
    //     CmdPacketTxInfo.curDataLen = BLE_MAX_SEND_PAYLOAD_LEN;
    // }
    // else if (CmdPacketTxInfo.SID > CmdPacketTxInfo.packetNum)
    // {
    //     memset(&CmdPacketTxInfo.dataBuf, 0, sizeof(CmdPacketTxInfo.dataBuf));
    //     CmdPacketTxInfo.status = TX_STA_IDLE;
    //     CmdPacketTxInfo.SID = BLE_SID_DEFAULE_VALUE;
    //     OSAL_EventDelete(COMP_BLE, EVENT_BLE_MULTIPLE_PACKET);
    //     return;
    // }
    // BLE_TASK_LOG_D("curDataLen:%d, sid:%d", CmdPacketTxInfo.curDataLen, CmdPacketTxInfo.SID);
    // BleTask_SendCmdPacket(CmdPacketTxInfo.random_value, CmdPacketTxInfo.totalDataLen, CmdPacketTxInfo.curDataLen, &CmdPacketTxInfo.dataBuf[(CmdPacketTxInfo.SID - 1) * BLE_MAX_SEND_PAYLOAD_LEN]);

    // CmdPacketTxInfo.SID += 1;

    //data_temp
    static uint8_t index = 0;

    if (data_length > 20)
    {
        BLE_TASK_LOG_HEX("BleTask ", &data_temp[index*20], 20);
        BLE_TASK_LOG_D("data_length:%d", data_length);
        Device_Write(vBLE_0, &data_temp[index*20], 20, BLE_CTRL_DATA);
        data_length -= 20;

        index++;
    }
    else
    {
        BLE_TASK_LOG_HEX("BleTask end", &data_temp[index*20], data_length);
        BLE_TASK_LOG_D("data_length end:%d", data_length);
        Device_Write(vBLE_0, &data_temp[index*20], data_length, BLE_CTRL_DATA);
        index = 0;
        if (CmdPacketTxInfo.status == TX_STA_BUSY && CmdPacketTxInfo.totalDataLen == CmdPacketTxInfo.curDataLen)
        {
            memset(&CmdPacketTxInfo.dataBuf, 0, sizeof(CmdPacketTxInfo.dataBuf));
            CmdPacketTxInfo.totalDataLen = 0;
            CmdPacketTxInfo.curDataLen = 0;
            CmdPacketTxInfo.status = TX_STA_IDLE;
        }
        data_length = 0;
        OSAL_EventDelete(COMP_BLE, EVENT_BLE_MULTIPLE_PACKET);
        memset (data_temp, 0, sizeof(data_temp));//
    }
   // index++; //

}
/**
 * @brief 发送命令数据
 *
 * @param [in] pData
 * @param [in] len
 *
 * @note
 */
static void BleTask_ProcessTxCmdMsg(uint8_t *pData, uint8_t len)
{
    uint32_t random_temp;
    uint8_t bindflag; // 绑定标志位
    if (pData == NULL || len == 0)
    {
        BLE_TASK_LOG_E("Ble send multi packet ERROR");
        return;
    }
    if (len > BLE_MAX_SEND_PAYLOAD_LEN)
    {
        /* 需要分包处理 */
        BLE_TASK_LOG_D("Ble send multi packet");
        //OSAL_EventRepeatCreate(COMP_BLE, EVENT_BLE_MULTIPLE_PACKET, 100, EVT_PRIORITY_MEDIUM);

        BLE_TASK_LOG_D("Ble send multi packet length %d", len);
        memcpy(CmdPacketTxInfo.dataBuf, pData, len);
        CmdPacketTxInfo.totalDataLen = len;

        if (CmdPacketTxInfo.totalDataLen % BLE_MAX_SEND_PAYLOAD_LEN == 0)
        {
            CmdPacketTxInfo.packetNum = CmdPacketTxInfo.totalDataLen / BLE_MAX_SEND_PAYLOAD_LEN;
        }
        else
        {
            CmdPacketTxInfo.packetNum = CmdPacketTxInfo.totalDataLen / BLE_MAX_SEND_PAYLOAD_LEN + 1;
        }
        CmdPacketTxInfo.status = TX_STA_BUSY;
    }
    else
    {
        BLE_TASK_LOG_D("Ble send simple packet");
        BLE_TASK_LOG_D("len:%d\n",len);
        /* 不需要分包处理，直接发送 */
        CmdPacketTxInfo.curDataLen = len;
        CmdPacketTxInfo.totalDataLen = len;
        CmdPacketTxInfo.status = TX_STA_BUSY;
        //获取随机码从app 传入; 其他指令从 下发的随机码 赋值就
        //random_temp = (((uint32_t)pData[4]) <<  24) + (((uint32_t)pData[5]) <<  16) + (((uint32_t)pData[6]) <<  8) + pData[7];

        if ((pData[10] == 0x80) && (pData[11] == 0x03))
        {
            random_temp = (((uint32_t)pData[4]) <<  24) + (((uint32_t)pData[5]) <<  16) + (((uint32_t)pData[6]) <<  8) + pData[7];
            random_get = random_temp;

        }
        else
        {
            random_temp = random_get;
        }
        BLE_TASK_LOG_D(">>>>>>>>random_temp:%x", random_temp);

        CmdPacketTxInfo.random_value = random_temp;//OSAL_SWAP32(random_temp); 
        
        //BLE_TASK_LOG_HEX("BleTask_ProcessTxCmdMsg>>>", pData, len);
        if ((pData[10] == 0x90) && (pData[11] == 0x60))
        {
            if(CmdPacketTxInfo.curDataLen > 0x16)
            {
                //BLE_TASK_LOG_HEX("BleTask_ProcessTxCmdMsg>>>", pData, len);
                #if 1
                memset(&CmdPacketTxInfo.dataBuf, 0, sizeof(CmdPacketTxInfo.dataBuf));
                CmdPacketTxInfo.totalDataLen = 0;
                CmdPacketTxInfo.curDataLen = 0;
                CmdPacketTxInfo.status = TX_STA_IDLE;
                #endif
                BLE_TASK_LOG_D("BleTask_ProcessTxCmdMsg return \n");
                return ;
            }
            
            bindflag = 1;
            OSAL_NvWrite(OSAL_OFFSET(BleNvData_stu_t, bind_flag), &bindflag, 1);
            BLE_TASK_LOG_D("bind_flag: 1");
        }
        BleTask_SendCmdPacket(CmdPacketTxInfo.random_value, len, len, pData);
        //static void BleTask_SendCmdPacket(uint16_t random, uint8_t totalLen, uint8_t curLen, uint8_t *dataBuf);
    }
}
/**
 * @brief  处理应用层下发的数据包（应用层->COMP）
 * @note
 * @return
 */
static void Ble_AplcSendPacket(BleCallbackMsg_t *pMsg)
{
    switch (pMsg->source)
    {
    case BLE_MSG_CMD: // 发的命令包
        BleTask_ProcessTxCmdMsg(pMsg->pData, pMsg->len);
        break;
    }
}
/**
 * @brief 多包数据接收处理
 *
 * @param [in] pData 包长度
 * @param [in] len 不包含校验的长度
 *
 * @note
 */
//static void BleTask_multi_packet_recv_handle(BleCmdPacket_stu_t *pCmdPacket, uint8_t len, uint8_t data_num, uint8_t data_end_flag)
static void BleTask_multi_packet_recv_handle(BleCmdPacket_stu_t *pCmdPacket, uint8_t len)   
{
    uint8_t i, index; // data_num = 0;  //data_num > 0 组包;     data_end_flag = 1， 结束组包，进行解析 
	//uint8_t BleStatus = 0;
    uint8_t Ble_PublishiData[BLE_COMP_BUFFER_SIZE]; //收到的命令参数 static
    //static uint8_t data_nums = 0;
    //data_nums = data_num;
    BLE_TASK_LOG_D(">>>>>len:%d", len);
    BLE_TASK_LOG_D("pCmdPacket->dataLen:%d", pCmdPacket->dataLen);
    //读一下加密标志位
    OSAL_NvRead(OSAL_OFFSET(BleNvData_stu_t, ble_encryptionflag), &ble_encryption_flag, 1);
    BLE_TASK_LOG_D("ble_encryption_flag read2:%d  ",ble_encryption_flag);
    if(ble_encryption_flag != 1)
    {
        ble_encryption_flag = 0;
    }
    memset(Ble_PublishiData, 0, BLE_COMP_BUFFER_SIZE);
    for (i = 0; i < BLE_PROTOCOL_RX_CMD_BUF_QTY; i++)
    {
        index = CmdPacketRxInfo.index + i;
        index = (index >= BLE_PROTOCOL_RX_CMD_BUF_QTY) ? index - BLE_PROTOCOL_RX_CMD_BUF_QTY : index;

        pCmdPacket->dataLen = OSAL_SWAP16(pCmdPacket->dataLen);
        if (pCmdPacket != NULL && CmdPacketRxInfo.DataBuffLen == 0)
        {
           BLE_TASK_LOG_D("RX Cmd packet, total:%d ", pCmdPacket->dataLen);//先考虑不用分包的情况
           //if (pCmdPacket->sid == 1 && pCmdPacket->dataLen == pCmdPacket->mdsec) //不用分包
           {
               //CmdPacketRxInfo.rxBuffer[index].SID = pCmdPacket->sid;
               CmdPacketRxInfo.rxBuffer[index].paramLen = pCmdPacket->dataLen - 8;//pCmdPacket->dataLen - 10;
               CmdPacketRxInfo.DataIndex = index;
               memcpy(CmdPacketRxInfo.rxBuffer[index].param, pCmdPacket->dataBuf, CmdPacketRxInfo.rxBuffer[index].paramLen);//
               //memcpy(CmdPacketRxInfo.rxBuffer[index].param, pCmdPacket->dataLen, CmdPacketRxInfo.rxBuffer[index].paramLen);//
               break;
           }
            // else if (pCmdPacket->sid == 1 && pCmdPacket->dataLen > pCmdPacket->mdsec) //分包的第一包数据
            // {
            //     CmdPacketRxInfo.DataBuffLen = 0;
            //     CmdPacketRxInfo.DataIndex = index;
            //     memcpy(CmdPacketRxInfo.DataBuff, pCmdPacket->dataBuf, pCmdPacket->mdsec);
            //     CmdPacketRxInfo.DataBuffLen += pCmdPacket->mdsec;
            //     break;
            // }
        }
        //else if (CmdPacketRxInfo.DataIndex == index && pCmdPacket->dataLen > BLE_MAX_SEND_PAYLOAD_LEN ) //分包的其他数据
        //{
            // BLE_TASK_LOG_D("RX Cmd packet, total:%d,  DataBuffLen:%d",  pCmdPacket->dataLen,  CmdPacketRxInfo.DataBuffLen);
            // memcpy(&CmdPacketRxInfo.DataBuff[CmdPacketRxInfo.DataBuffLen], pCmdPacket->dataBuf, pCmdPacket->mdsec);
            // CmdPacketRxInfo.DataBuffLen += pCmdPacket->mdsec;//

            // if (CmdPacketRxInfo.DataBuffLen == pCmdPacket->dataLen) //分包接收完成，上发应用层处理
            // {
            //     CmdPacketRxInfo.rxBuffer[index].paramLen = pCmdPacket->dataLen;
            //     memcpy(CmdPacketRxInfo.rxBuffer[index].param, CmdPacketRxInfo.DataBuff, CmdPacketRxInfo.rxBuffer[index].paramLen);
            // }
            // break;
        //}
    }

    //不分包和分包完成的数据，上报给应用层处理 ，其他的不处理 
    //if (CmdPacketRxInfo.DataBuffLen == pCmdPacket->dataLen)
    
    //if ( (data_nums == 0) || (data_nums > 0 && data_end_flag == 1) )
    //{
        //if( data_nums == 0)
        //{
            if (pCmdPacket->dataLen == (len - 2) )
            {
                BLE_TASK_LOG_D("001 publish, idex:%d", CmdPacketRxInfo.index);
                CmdPacketRxInfo.DataBuffLen = 0;
                memset(CmdPacketRxInfo.DataBuff, 0, sizeof(CmdPacketRxInfo.DataBuff));
                //BLE_TASK_LOG_HEX("BleTask_MessagePublish", CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen);
                BLE_TASK_LOG_D("publish, paramLen:%d", CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen);
                    
                if((pCmdPacket->dataBuf[2] != 0x80) && (pCmdPacket->dataBuf[3] != 0x03))
                {
                    random_get = pCmdPacket->random_code;
                    BLE_TASK_LOG_D("random_get:%x \n", random_get);
                } 
                if (ble_encryption_flag == 0) 
                {
                    BLE_TASK_LOG_D("ble_encryption_flag: 0");
                    BleTask_MessagePublish(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, 0, PUBLISH_APP_CMD);
                }
                else if (ble_encryption_flag == 1) //解密后再发给应用层
                {
                    BLE_TASK_LOG_D("ble_encryption_flag: 1");
                    /* AES128-ECB解密 */ //AES128_DECRYPTION_PKCS7
                    OSAL_Crypto(AES128_DECRYPTION, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, Ble_PublishiData, aeskey);         
                    // 发送数据到应用层
                    // BLE_TASK_LOG_HEX("Ble_PublishiData", Ble_PublishiData, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen);                     
                    BleTask_MessagePublish(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, Ble_PublishiData, 0, PUBLISH_APP_CMD);
                }                      
                memset(&CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex], 0, sizeof(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex]));
                CmdPacketRxInfo.index = (CmdPacketRxInfo.index >= BLE_PROTOCOL_RX_CMD_BUF_QTY - 1) ? 0 : CmdPacketRxInfo.index + 1;
            }

        //}
        // else
        // {
        //         BLE_TASK_LOG_D("002 publish, idex:%d", CmdPacketRxInfo.index);
        //         CmdPacketRxInfo.DataBuffLen = 0;
        //         memset(CmdPacketRxInfo.DataBuff, 0, sizeof(CmdPacketRxInfo.DataBuff));
        //         BLE_TASK_LOG_HEX("BleTask_MessagePublish", CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen);
        //             BLE_TASK_LOG_D("publish, paramLen:%d", CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen);
                    
        //         if((pCmdPacket->dataBuf[2] != 0x80) && (pCmdPacket->dataBuf[3] != 0x03))
        //         {
        //             random_get = pCmdPacket->random_code;
        //             BLE_TASK_LOG_D("random_get:%x \n", random_get);
        //         } 
        //         if (ble_encryption_flag == 0) 
        //         {
        //             BleTask_MessagePublish(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, 0, PUBLISH_APP_CMD);
        //         }
        //         else if (ble_encryption_flag == 1) //解密后再发给应用层
        //         {
        //             /* AES128-ECB解密 */
        //             OSAL_Crypto(AES128_DECRYPTION, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, Ble_PublishiData, aeskey);
        //             //
        //             BleTask_MessagePublish(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, Ble_PublishiData, 0, PUBLISH_APP_CMD);
        //         }
                
                                
        //             //BleTask_MessagePublish(4, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, NULL, PUBLISH_APP_CMD); //ok
        //             //      BleTask_MessagePublish(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].paramLen, CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex].param, NULL, PUBLISH_APP_CMD); //ok
                    
        //             //BleTask_MessagePublish(1, &BleStatus, NULL, PUBLISH_BLE_STATUS);
                    
        //         memset(&CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex], 0, sizeof(CmdPacketRxInfo.rxBuffer[CmdPacketRxInfo.DataIndex]));
        //         CmdPacketRxInfo.index = (CmdPacketRxInfo.index >= BLE_PROTOCOL_RX_CMD_BUF_QTY - 1) ? 0 : CmdPacketRxInfo.index + 1;
        // }

        //i = 0;
        //index = 0;
        //data_nums = 0;
        //Ble_PublishiData 清0;
        //memset(Ble_PublishiData, 0, BLE_COMP_BUFFER_SIZE);
    //}
}
/**
 * @brief
 *
 * @param [in] len
 * @param [in] pData
 *
 * @note
 */
static void BleTask_packet_data_handle(uint8_t len, uint8_t *pData)
{
    uint16_t crc_16 = 0;
    static uint8_t tempBuff[BLE_COMP_BUFFER_SIZE] = {0};
    BleCmdPacket_stu_t *bleCmd = NULL;
    static uint16_t data_len = 0;
    static uint16_t data_len_temp = 0;
    //static uint8_t data_num = 0;//--
    //static uint8_t data_end = 0;
    static uint8_t Buff_index = 0;

    if (pData == NULL || len == 0)
    {
        BLE_TASK_LOG_W("Recv packet Data or len error");
        return;
    }

    BLE_TASK_LOG_D(">>>>>len:%d", len);
    BLE_TASK_LOG_D("Buff_index:%d", Buff_index);
    //memcpy(tempBuff, pData, len);
    memcpy(&tempBuff[Buff_index], pData, len);

    if (tempBuff[0] == 0xA5 && tempBuff[1] == 0xE5 && Buff_index == 0)
    {
        data_len =  ( (uint16_t)tempBuff[2] << 8 ) + tempBuff[3]; 
        data_len_temp = data_len;
        BLE_TASK_LOG_D("tempBuff[2] = %d ,tempBuff[3] %d", tempBuff[2], tempBuff[3]);
        BLE_TASK_LOG_D(">>>>>data_len = %d", data_len);
    }

    //bleCmd = (BleCmdPacket_stu_t *)tempBuff;
    BLE_TASK_LOG_HEX("recv packet pData:", pData, len);
    //if( data_len <= 16) //app 20字节为1包  
    if (tempBuff[0] == 0xA5 && tempBuff[1] == 0xE5 && data_len <= 16)
    {
        crc_16 = CRC16_Cal(&tempBuff[2], len - 4);  //
        if ( crc_16 != ( ( ((uint16_t)tempBuff[len - 2]) << 8) + tempBuff[len - 1] ) )
        {
            memset(tempBuff, 0, BLE_COMP_BUFFER_SIZE);
            BLE_TASK_LOG_W("check crc_16 error, crc_16:0x%x, recvcrc:0x%x 0x%x", crc_16, tempBuff[len-2],tempBuff[len-1]);
            return;
        }
        //BLE_TASK_LOG_W("check crc_16 ok, crc_16:0x%x, recvcrc:0x%x 0x%x", crc_16, tempBuff[len-2],tempBuff[len-1]);
        bleCmd = (BleCmdPacket_stu_t *)tempBuff;
        BleTask_multi_packet_recv_handle(bleCmd, len - 2);//0, data_end
        memset(tempBuff, 0, BLE_COMP_BUFFER_SIZE);
        Buff_index = 0;
        data_len = 0;
        data_len_temp = 0;//
    }
    else
    {
        //TODO: 合并之后在 多包里面进行 CRC16 校验  
        if(data_len_temp > 16)
        {
            //data_num++;
            if(data_len_temp >= 20)
            {
                data_len_temp -= 20;
            }
            else
            {
                data_len_temp -= 16;
            }
            Buff_index += 20;//
            //BLE_TASK_LOG_D("data_len_temp = %d", data_len_temp);
           // BleTask_multi_packet_recv_handle(bleCmd, 16, data_num, data_end);  //组合好，最后一包再去处理
        }
        else
        {
            //data_num++;
            //data_end = 1;
            BLE_TASK_LOG_D("data_len = %d", data_len);
            BLE_TASK_LOG_HEX("tempBuff:", tempBuff, data_len + 2);
            bleCmd = (BleCmdPacket_stu_t *)tempBuff;
            //BleTask_multi_packet_recv_handle(bleCmd, data_len, data_num, data_end); //长度处理  
             BleTask_multi_packet_recv_handle(bleCmd, data_len + 2); //-- 没有加上crc 
            //data_num = 0;
            //data_end = 0;
            memset(tempBuff, 0, BLE_COMP_BUFFER_SIZE);
            Buff_index = 0;
            data_len = 0;
            data_len_temp = 0;
        }
        
    }
    
    //BLE_TASK_LOG_W("check crc_16 ok, crc_16:0x%x, recvcrc:0x%x 0x%x", crc_16, tempBuff[len-2],tempBuff[len-1]);
    //BleTask_multi_packet_recv_handle(bleCmd, len - 2);
}

/**
 * @brief  蓝牙中断处理
 * @note
 * @return
 */
static void Ble_Int_Irq_Handler(VirtualHardware_enum_t dev, void *pBuf, uint32_t len) //
{
    BleIRQMsg_t rev_msg;
    memset(&rev_msg, 0x00, sizeof(BleIRQMsg_t));
    rev_msg.len = len & 0xff;
    rev_msg.type = (len >> 16) & 0xff;
    memcpy(rev_msg.pData, pBuf, rev_msg.len);

    // BLE_TASK_LOG_D("IRQ len: %d, IRQ type: %d\r\n", rev_msg.len, rev_msg.type);
    // 存数据
    if (OSAL_RingBufferWrite(rbBleHandle, &rev_msg) == SUCCESS)
    {
        /* 创建ISR事件 */
        OSAL_EventCreateFromISR(COMP_BLE);
    }
}

/**
 * @brief  处理蓝牙发来的数据
 * @note
 * @return
 */
static void Ble_ParseRxPacket()//
{
    BleIRQMsg_t packet;
    uint8_t seq = 0;
    uint16_t crc16_value;
    uint8_t bindflag = 0;
    while (OSAL_RingBufferRead(rbBleHandle, (uint8_t *)&packet) == SUCCESS)
    {
        if (packet.type == PUBLISH_BLE_MAC) // 协议栈启动成功,给SystemID赋值
        {
            BleTask_MessagePublish(packet.len, packet.pData, NULL, PUBLISH_BLE_MAC); // MAC上报给应用层
            //OSAL_NvRead(OSAL_OFFSET(BleNvData_stu_t, bind_flag), &bindflag, sizeof(bindflag));
            //BLE_TASK_LOG_D("Read bindflag: %d", bindflag);
            //Device_Write(vBLE_0, &bindflag, sizeof(bindflag), BLE_CTRL_SET_BINDFLAG);
        }
        else if (packet.type == PUBLISH_BLE_STATUS)
        {
            uint8_t BleStatus = packet.pData[0];
            BLE_TASK_LOG_D("ISR type:%d", BleStatus);
            if (BleStatus == 1) // 与手机连接成功，赋值配网状态
            {
                BLE_TASK_LOG_D("ble connect");
            }
            else // 断开蓝牙/无法连接
            {
                BLE_TASK_LOG_D("ble disconnect");
                //OSAL_NvRead(OSAL_OFFSET(BleNvData_stu_t, bind_flag), &bindflag, sizeof(bindflag));
                //Device_Write(vBLE_0, &bindflag, sizeof(bindflag), BLE_CTRL_SET_BINDFLAG);
            }
            BleTask_MessagePublish(1, &BleStatus, NULL, PUBLISH_BLE_STATUS); // 蓝牙连接状态上报给应用层
        }
        else // 处理手机下发的信息
        {
			#if 1 // 
            //BLE_TASK_LOG_HEX("-->>>Ble_ParseRxPacket:", packet.pData, packet.len);
            //OSAL_SetTaskStatus(TASK_STA_ACTIVE);//----------
            BleTask_packet_data_handle(packet.len, packet.pData);
			#endif
				#if 0
				BLE_TASK_LOG_HEX("-->>>Ble_ParseRxPacket:", packet.pData, packet.len);
				Device_Write(vBLE_0, packet.pData, packet.len, BLE_CTRL_DATA);
				#endif
        }
    }
}

/**
 * @brief  处理邮箱发来的数据
 * @note
 * @return
 */
static void Ble_ProcessMbox(uint8_t *msg) //
{
    switch (msg[0])
    {
    case BLE_CTRL_DATA: //数据
        Ble_AplcSendPacket((BleCallbackMsg_t *)&msg[1]);
        break;

    case BLE_CTRL_CONNECT: // 控制蓝牙连接状态
        if (msg[1] == 0)
        {
            Device_Write(vBLE_0, NULL, 0, BLE_CTRL_DISCONNECT); //断开蓝牙连接
        }
        break;

    case BLE_CTRL_CALIBRATION: // 开启校准
        Device_Write(vBLE_0, &msg[1], 9, BLE_CTRL_CALIBRATION);
        break;

    case BLE_CTRL_SET_MAC:     // 设置广播地址
        Device_Write(vBLE_0, &msg[1], 6, BLE_CTRL_SET_MAC); 
        break;

     case BlE_CTRL_ENCRYPTION: // 控制加密标志
        if (msg[1] == 0)
        {
            //不加密
            ble_encryption_flag = 0;
            OSAL_NvWrite(OSAL_OFFSET(BleNvData_stu_t, ble_encryptionflag), &ble_encryption_flag, 1);
            BLE_TASK_LOG_D("ble_encryption_flag 0");
        }
        else if (msg[1] == 1)
        {
            //加密
             ble_encryption_flag = 1;
            OSAL_NvWrite(OSAL_OFFSET(BleNvData_stu_t, ble_encryptionflag), &ble_encryption_flag, 1);
            BLE_TASK_LOG_D("ble_encryption_flag 1");
        }
        break;
        
    default:
        break;
    }
}

/**
 * @brief  蓝牙初始化
 * @note
 * @return
 */
static void Ble_Init(void)//
{
    if (rbBleHandle == NULL)
    {
        rbBleHandle = OSAL_RingBufferCreate(BLE_RB_RXBUF_LENGTH, sizeof(BleIRQMsg_t));
        /* 注册中断回调 */
        Device_RegisteredCB(vBLE_0, Ble_Int_Irq_Handler);
        Device_Enable(vBLE_0);
        BLE_TASK_LOG_D("ble Init\r\n");
    }

    memset(&CmdPacketRxInfo, 0, sizeof(CmdPacketRxInfo));
    memset(&CmdPacketTxInfo, 0, sizeof(CmdPacketTxInfo));
    CmdPacketTxInfo.status = TX_STA_IDLE;
}

/**
 * @brief  获取设备gatt和频偏
 * @param  data: 数据域指针
 */
void Ble_GetGATT(uint8_t *data)//
{
    Device_Read(vBLE_0, data, 3, PUBLISH_CALIBRATION_FREQ);
}

/**
 * @brief  BLE任务函数
 *
 * @note
 *
 * @param  event：当前任务的所有事件
 *
 * @return 返回未处理的事件
 */
static uint32_t Ble_Task(uint32_t event)
{
    /* 系统启动事件 */
    if (event & EVENT_SYS_START)
    {
        BLE_TASK_LOG_D("ble task start\r\n");
        Ble_Init();

        // OSAL_NvRead(OSAL_OFFSET(BleNvData_stu_t, ble_encryptionflag), &ble_encryption_flag, 1);
        // BLE_TASK_LOG_D("ble_encryption_flag read:%d  ",ble_encryption_flag);
        return (event ^ EVENT_SYS_START);
    }

    /* 系统邮箱事件 */
    if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[100] = {0};
        if (CmdPacketTxInfo.status == TX_STA_IDLE)
        {
            if (OSAL_MboxAccept(buffer))
            {
                Ble_ProcessMbox(buffer);
                OSAL_EventSingleCreate(COMP_BLE, EVENT_SYS_MBOX, 20, EVT_PRIORITY_MEDIUM);
            }
        }
        else
        {
            OSAL_EventSingleCreate(COMP_BLE, EVENT_SYS_MBOX, 20, EVT_PRIORITY_MEDIUM);
        }

        return (event ^ EVENT_SYS_MBOX);
    }

    /* BLE中断事件 */
    if (event & EVENT_SYS_ISR)
    {
        BLE_TASK_LOG_D("BLE ISR EVENT\r\n");
        Ble_ParseRxPacket();//
        return (event ^ EVENT_SYS_ISR);
    }

    /* 分包处理事件 */
    if (event & EVENT_BLE_MULTIPLE_PACKET)
    {
        BleTask_Multi_packet_send();
        return (event ^ EVENT_BLE_MULTIPLE_PACKET);
    }

    /* 测试 */
    if (event & EVENT_TEST)
    {
        static test = 0;
        test++;
        BLE_TASK_LOG_D("BLE test timeCount:%d, test:%d\r\n", OSAL_GetTickCount(), test);
        if (test == 5)
        {
            test = 0;
            OSAL_EventDelete(COMP_BLE, EVENT_TEST);
            BleTask_MessagePublish(1, NULL, 0, PUBLISH_HEART_BEAT); // 广播关闭时上报给应用层
        }
        return (event ^ EVENT_TEST);
    }

    return 0;
}

COMPONENT_TASK_EXPORT(COMP_BLE, Ble_Task, 10);
